let watcher = null;
function autorun(fn) {
  watcher = fn;
  fn();
  watcher = null;
}

function observable(target) {
  const _target = { ...target };
  let proxy = {};
  let subs = new Map();

  Object.keys(target).forEach((key) => {
    Object.defineProperty(proxy, key, {
      get() {
        if (watcher) {
          let watchers = subs.get(key);
          if (!watchers) {
            subs.set(key, new Set([watcher]));
          } else {
            watchers.add(watcher);
          }
        }
        const value = _target[key];
        console.log(`read ${key} = ${value}`, subs);
        return value;
      },
      set(value) {
        console.log(`set ${key} = ${value}`);
        _target[key] = value;
        let watchers = subs.get(key);
        // if (watcher) {
        //   watchers.forEach((watcher) => {
        //     watcher();
        //   });
        // }
        watchers.forEach((watcher) => {
          watcher();
        });
        return value;
      },
    });
  });
  return proxy;
}

const data = observable({ age: 10, name: 'Zchary' })
autorun(() => { console.log(`autorun: ${data.name} is ${data.age} years old`) })
// autorun(() => { console.log(`autorun: ${data.name} is ${data.age * 2}  years old`) })
function changeAge() {
    for (let i = 0; i < 5; i++) {
        setTimeout(() => {
            data.age++;
        }, 1000 * (i+1))
    }
}

